import re
import sets
from django.template.loader import find_template_source
from django.template import TemplateDoesNotExist

from tppt.lib import exceptions
def template_exists(template_name):
	try:
		find_template_source(template_name)
		return True
	except TemplateDoesNotExist:
		return False
	

def ceil(x):
	return int(round(x+.4999))

def filter(pred, lst):
	res=[]
	for itm in lst:
		if pred(itm):
			res.append(itm)
	return res

def union_ranges(*args):
	res=[]
	for rng in args:
		if not res:
			res=rng
		else:
			last=res[-1]
			for i in range(0,len(rng)):
				if rng[i]>last:
					res.extend(rng[i:])
					break
	return res

def update_existing(dict, src, keep_type=False):
	for key in dict:
		if key in src:
			if keep_type:
				if isinstance(dict[key], int):
					dict[key]=int(src[key])
				else:
					dict[key]=src[key]
			else:
				dict[key]=src[key]
				

def is_instance_of_any(object, classes):
	for cl in classes:
		if isinstance(object, cl):
			return True
	return False

camelcase_to_underscore = lambda str: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', '_\\1', str).lower().strip('_')
camelcase_to_words = lambda str: camelcase_to_underscore(str).replace('_', ' ').capitalize() 

def simplify_query_dict(query_dict):
	res={}
	for key in query_dict:
		dict_val=query_dict[key]
		if isinstance(dict_val, str) or isinstance(dict_val, unicode):
			val=dict_val
		else:
			if len(dict_val)>1:
				raise exceptions.InvalidOperationError('Multiple values for one parameter.')
			val=dict_val[0]
		res[key]=val
	return res


class UniqueList(list):
	"List that cannot contain the same value multiple times."
	
	def __init__(self):
		self.key_set=sets.Set()
	
	def __contains__(self, item):
		if isinstance(item, models.BaseModel):
			key=str(item.key())
			return key in self.key_set
		return super(UniqueList, self).__contains__(item)
		
	
	def append(self, item):
		"""Appends value to list.
		
		If value is already present in the list, nothing is inserted."""

		if item not in self:
			if isinstance(item, models.BaseModel):
				self.key_set.add(str(item.key()))
			super(UniqueList, self).append(item)

	def extend(self, lst):
		"""Appends values from given list.
		
		If some value is already present in the list, it is not inserted."""
		for item in lst:
			self.append(item)

def human_trunc(value, maxsize, stopper='...'):
	stoplen = len(stopper)
	if len(value) > maxsize and maxsize > stoplen:
		return value[:(maxsize-stoplen)] + stopper
	else:
		return value[:maxsize]
	

def humanize_reference(target, context, model=None):
	from appengine_django import models
	if isinstance(target,  models.BaseModel):
		entity=target
		key=None
		capt=entity.get_caption()
	else:
		if not model:
			from gaev import exceptions
			raise exceptions.InsufficientArgumentsError()
		entity=None
		key=target
		capt=model.get_entity_caption(key)
	if context.use_html:
		from gaev.actions.url import get_action_url
		url=get_action_url('details', object=entity,  model=model,  key=key)
		return '<a href="%s">%s</a>' % (url, capt)
	else:
		return capt 